package main

import (
	"context"
	"fmt"
	"github.com/go-redis/redis/v8"
	"github.com/go-redsync/redsync/v4"
	"github.com/go-redsync/redsync/v4/redis/goredis/v8"
	"log"
	"time"
)

var rdb *redis.Client
var ctx = context.Background()
var rs *redsync.Redsync

// go get -u github.com/go-redis/redis/v8
func main() {
	testPing()
	testStringStructure()
	testHashStructure()
	testListStructure()
	testUsePipeline()
	testDistributedLock()
}
func init() {
	rdb = redis.NewClient(&redis.Options{
		Addr:         "localhost:6379", // Redis 服务器地址
		Password:     "",               // 密码（如果需要）
		DB:           0,                // 数据库索引
		PoolSize:     10,               // 连接池大小
		MinIdleConns: 5,                // 最小空闲连接数
	})

	//*redsync.Redsync
	pool := goredis.NewPool(rdb)
	rs = redsync.New(pool)
}

func testDistributedLock() {
	// 2. 创建互斥锁
	mutex := rs.NewMutex("order-lock",
		redsync.WithExpiry(10*time.Second),           // 锁自动过期时间
		redsync.WithTries(3),                         // 最大尝试次数
		redsync.WithRetryDelay(500*time.Millisecond), // 重试间隔
	)
	// 3. 获取锁
	err := mutex.Lock()
	if err != nil {
		log.Fatalf("failed to acquire lock: %v", err)
	}
	defer func() {
		// 4. 释放锁
		if ok, err := mutex.Unlock(); !ok || err != nil {
			log.Printf("释放锁失败: %v", err)
		}
	}()
}

// testPing
//
//	@Description: 测试ping-pang
func testPing() {
	ping, err := rdb.Ping(ctx).Result()
	if err != nil {
		log.Fatalf("failed to connect to Redis: %v", err)
	}
	fmt.Println("Connected to Redis:", ping)
}

// testStringStructure
//
//	@Description: 测试string结构
func testStringStructure() {
	err := rdb.Set(ctx, "no", "100", 0).Err()
	if err != nil {
		log.Fatalf("设置string-key err=%v", err)
	}
	val, err := rdb.Get(ctx, "no").Result()
	if err != nil {
		log.Fatalf("获取string-key err=%v", err)
	}
	fmt.Printf("%s \n", val)
}

// testHashStructure
//
//	@Description: 测试hash结构
func testHashStructure() {
	err := rdb.HSet(ctx, "user", "name", "zhangsan").Err()
	if err != nil {
		log.Fatalf("设置hash-key err=%v", err)
	}
	val, err := rdb.HGet(ctx, "user", "name").Result()
	if err != nil {
		log.Fatalf("获取hash-key err=%v", err)
	}
	fmt.Printf("%s \n", val)
}

// testListStructure
//
//	@Description: 测试list结构
func testListStructure() {
	err := rdb.LPush(ctx, "list", "1", "2", "3").Err()
	if err != nil {
		log.Fatalf("设置list-key err=%v", err)
	}
	val, err := rdb.LRange(ctx, "list", 0, -1).Result()
	if err != nil {
		log.Fatalf("获取list-key err=%v", err)
	}
	fmt.Printf("%v \n", val)
}

// testUsePipeline
//
//	@Description: 测试管道
func testUsePipeline() {
	// 使用管道提高性能
	pipeline := rdb.Pipeline()
	pipeline.Set(ctx, "key1", "value1", 0)
	pipeline.Set(ctx, "key2", "value2", 0)
	_, err := pipeline.Exec(ctx)
	if err != nil {
		log.Fatalf("pipeline error: %v", err)
	}
	fmt.Println("Pipeline executed successfully")
	val1, _ := rdb.Get(ctx, "key1").Result()
	val2, _ := rdb.Get(ctx, "key2").Result()
	fmt.Printf("key1=%s key2=%s", val1, val2)
}
